#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# This script verifies if the input of the simulator is such that the simulation will ever end.
#

import sys

SEPARATOR='\t'

def get_lines(f):
    h = open(f, 'r')
    try:
        for line in h.readlines():
            yield line.strip()
    finally: h.close()

def get_machine_to_operations_per_second(f):
    
    result = {}
    for line in get_lines(f):
        machine_id, operations = line.split(SEPARATOR)
        result[machine_id] = int(operations)
    return result

def get_max_machines_availability(f):
    
    result = {}
    for line in get_lines(f):
        machine_id, _, availability = line.split(SEPARATOR)
        if machine_id not in result:
            result[machine_id] = max(result.get(machine_id, -1), int(availability))
    return result

def get_jobs_runtime(f):
    
    result = []
    for line in get_lines(f):
        _, runtime = line.split(SEPARATOR)
        result.append(int(runtime))
    return result

if __name__ == '__main__':
    
    if len(sys.argv) != 5:
        print 'Error! Usage: <machineAvailabilityWorkload> <jobSubmissionWorkload> <machineIdToOperationsPerSecond> <timeToOperations>'
        print '<machineAvailabilityWorkload>    : The file which has the machine availability workload;'
        print '<jobSubmissionWorkload>          : The file which has the job submission workload;'
        print '<machineIdToOperationsPerSecond> : The file which has the machine id to operations per second info;'
        print '<timeToOperations>               : The factor that converts one second of a job in number of operations.'
        sys.exit(1)
        
    machine_availability_workload_file, job_submission_workload_file, machine_id_to_operations_per_second_file, time_to_operations = sys.argv[1:]
    time_to_operations = int(time_to_operations)
    
    machine_to_operations_per_second = get_machine_to_operations_per_second(machine_id_to_operations_per_second_file)
    max_machines_availability = get_max_machines_availability(machine_availability_workload_file)
    assert len(machine_to_operations_per_second) >= len(max_machines_availability) 
    jobs_runtime = get_jobs_runtime(job_submission_workload_file)

    max_machine_operations = -1
    for machine in max_machines_availability:
        max_machine_operations = max(max_machine_operations, machine_to_operations_per_second[machine] * max_machines_availability[machine])
    
    jobs_operations = [time_to_operations * runtime for runtime in jobs_runtime]
    
    for job_operations in jobs_operations:
        assert job_operations <= max_machine_operations, 'Job too big (No. operations): %d, max operations to execute: %d' % (job_operations, max_machine_operations)
    